Skip to content

[pull] main from MetaMask:main#498

Merged
pull[bot] merged 88 commits into
Reality2byte:mainfrom
MetaMask:main
Feb 4, 2026
Merged

[pull] main from MetaMask:main#498
pull[bot] merged 88 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Feb 4, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

metamaskbot and others added 30 commits January 22, 2026 20:47
…lidation and improve error handling (#25076)

- fix(predict): cp-7.63.0 add transaction validation and improve error
handling (#25013)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Adds comprehensive validation for deposit transactions to prevent
silent failures causing 'not enough input to decode' errors.

Changes:
- Add transaction validation in depositWithConfirmation:
  - Verify transaction and params objects exist
  - Validate 'to' address format (0x prefix, 42 chars)
  - Validate data field exists and has valid hex format
  - Enforce minimum data length (10 chars)
- Improve error handling in polymarket safe utils:
  - Re-throw errors in getDeployProxyWalletTransaction instead of
    returning undefined
  - Add try-catch with proper error propagation in
    getProxyWalletAllowancesTransaction
  - Add call data length validation
- Update tests with valid mock addresses/data
- Add test coverage for all new validation error scenarios

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: null

## **Related issues**

Fixes: #24804

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Strengthens deposit flow reliability and surfaces clearer errors.
> 
> - Add `validateDepositTransactions` and integrate into
`depositWithConfirmation`; log tx metadata and enforce `to` address
format, hex data presence/format, and minimum data length
> - Improve Polymarket Safe utils: rethrow errors in
`getDeployProxyWalletTransaction`, wrap
`getProxyWalletAllowancesTransaction` in try/catch with call data length
validation and contextual error messages
> - Update tests with valid addresses/data and add coverage for all new
validation/error cases (including user-denied signatures)
> - Minor test event updates to use realistic `from/to/data` fields
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
bdc37dd. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[87bc552](87bc552)

Co-authored-by: Caainã Jeronimo <caainaje@gmail.com>
…es to analytics events (#25123)

- feat(predict): cp-7.63.0 add game properties to analytics events
(#25065)

## **Description**

Add new analytics properties to Predict market events to improve
tracking for sports/game-based prediction markets:

1. **PREDICT_MARKET_DETAILS_OPENED** and **PREDICT_TRADE_TRANSACTION**
events now include:
   - `market_slug` - Market slug identifier
   - `game_id` - Game identifier
   - `game_start_time` - Game start timestamp
   - `game_league` - League name (e.g., "NBA", "NFL")
   - `game_status` - Game status (e.g., "not_started", "live", "final")
   - `game_period` - Current game period (nullable)
   - `game_clock` - Current game clock (nullable)

2. **SHARE_ACTION** event tracking added for share button interactions:
   - `status` - Share status: "initiated", "success", or "failed"
   - `market_id` - Market identifier
   - `market_slug` - Market slug

These changes align with the Segment schema updates in [segment-schema
PR #429](https://github.com/Consensys/segment-schema/pull/429).

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: 
 - https://consensyssoftware.atlassian.net/browse/PRED-422
 - https://consensyssoftware.atlassian.net/browse/PRED-505

## **Manual testing steps**

```gherkin
Feature: Predict Analytics Events

  Scenario: Game properties sent on market details view
    Given user navigates to a sports prediction market
    When user opens the market details view
    Then PREDICT_MARKET_DETAILS_OPENED event includes game properties (game_id, game_league, game_status, etc.)

  Scenario: Game properties sent on trade transaction
    Given user is on a sports prediction market buy/sell preview
    When user completes a buy or sell transaction
    Then PREDICT_TRADE_TRANSACTION event includes game properties

  Scenario: Share action tracking
    Given user is viewing a prediction market with game details
    When user taps the share button
    Then SHARE_ACTION event is sent with status "initiated"
    And when share completes successfully, SHARE_ACTION event is sent with status "success"
    And when share fails, SHARE_ACTION event is sent with status "failed"
```

## **Screenshots/Recordings**

N/A - Analytics only change, no UI modifications

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Enhances Predict analytics coverage for sports markets and sharing
flows.
> 
> - Adds `market_slug`, `game_id`, `game_start_time`, `game_league`,
`game_status`, `game_period`, `game_clock` to
`PREDICT_TRADE_TRANSACTION` and `PREDICT_MARKET_DETAILS_OPENED` via
`PredictController`, with type updates in `providers/types.ts`
> - Introduces `PredictShareStatus` and new `SHARE_ACTION` tracking in
`PredictController.trackShareAction`
> - Updates `PredictShareButton` to send `SHARE_ACTION` events on press
(initiated) and on result (success/failed), and accept/pass
`marketSlug`; propagates prop from market detail/game views
> - Adds comprehensive tests for share URL, toasts, edge cases, and
analytics status flows
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7040a85. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[a2d49c6](a2d49c6)

Co-authored-by: Luis Taniça <matallui@gmail.com>
…bowl sport card to wallet Carousel (#25141)

- feat(predict): cp-7.63.0 add Predict Superbowl sport card to wallet
Carousel (#25062)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

This PR integrates the Predict Superbowl sport card into the wallet home
Carousel component. When a `predict-superbowl` slide is configured in
Contentful with a valid `marketId`, the Carousel renders a
`PredictMarketSportCardWrapper` instead of the standard carousel cards.

**Key changes:**
- Added `PredictMarketSportCardWrapper` component that fetches market
data and renders `PredictMarketSportCard`
- Added `metadata` field to `CarouselSlide` type to support passing
`marketId`
- Added `CAROUSEL` entry point for Predict navigation tracking
- Modified `PredictSportCardFooter` to navigate through `PREDICT.ROOT`
when accessed from Carousel
- Added close button functionality to `PredictMarketSportCard` for
dismissing the banner
- Added comprehensive unit tests for all new components and integration

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?

AI agent: Be specific about what you changed and why. Include context
about the fix/feature, not generic descriptions.
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)

AI agent: Use format `CHANGELOG entry: [fix/feat/chore]: [User-facing
description in past tense]`.
Examples: `fix: resolved token name display issue`, `feat: added dark
mode toggle`, `chore: updated dependencies`.
For non-user-facing changes, use `CHANGELOG entry: null`.
-->

CHANGELOG entry: null

## **Related issues**

<!--
AI agent: Replace with `Fixes: #[ISSUE_NUMBER]` using the actual issue
number you're implementing.
-->

Fixes:

## **Manual testing steps**

<!--
AI agent: Write specific, contextual Gherkin steps based on what you
actually implemented.
Do NOT use generic placeholders like "my feature name". Be concrete
about the feature, scenario, and steps.
-->

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

https://www.loom.com/share/232ede925eef4c75ab9e322573d03363

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

<!--
AI agent: Check ALL boxes in this section (mark all as [x]).
-->

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

<!--
AI agent: Leave ALL boxes unchecked ([ ]) - these are for reviewers to
check, not the author.
-->

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Integrates a special Predict Superbowl experience into the wallet
carousel driven by Contentful.
> 
> - Adds `metadata` to `CarouselSlide` and maps Contentful `metadata`
through `fetchCarouselSlidesFromContentful`
> - When a `predict-superbowl` slide exists with `metadata.marketId`,
hides that slide from the stack and renders
`PredictMarketSportCardWrapper` instead
> - Implements dismissal for the sport card via carousel banner state
and fires "Banner Display" metrics on load
> - Introduces `PredictMarketSportCardWrapper` to fetch market data and
render `PredictMarketSportCard`; adds optional close button to the card
> - Adds `CAROUSEL` entry point and updates `PredictSportCardFooter` to
navigate via `PREDICT.ROOT` when invoked from the carousel
> - Updates types (`PredictCarouselMetadata`, `PredictEntryPoint`,
`CarouselSlide.metadata`) and adds constants
(`PREDICT_SUPERBOWL_VARIABLE_NAME`)
> - Comprehensive tests for carousel integration, wrapper/card behavior,
footer navigation, and analytics
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d6a7ef8. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[67f890f](67f890f)

Co-authored-by: Caainã Jeronimo <caainaje@gmail.com>
…k feed cp-7.63.0 (#25164)

- fix: compute spread from HL bbo top-of-book feed cp-7.63.0 (#25145)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
                                    
  ### Summary                                             
                                                      
- Fixes incorrect spread display in Perps order book that changed when
users change the aggregate dropdown
- Spread now uses BBO (best bid/offer) feed instead of aggregated
L2Book, matching Hyperliquid UI
  behavior                                            
- Adds missing test coverage for `subscribeToOrderBook` L2Book
subscriptions
  
  https://consensyssoftware.atlassian.net/browse/TAT-2425           
                                                      
  ### Problem                                             
                                                      
The spread displayed under the order book depth chart was incorrect and
would change when the use changed the aggregation dropdown. This
diverged from Hyperliquid's UI where spread remains stable regardless of
grouping selection.
                                                      
Root cause: Spread was derived from aggregated orderbook levels. When
requesting an aggregated book, the best bid/ask are bucketed/rounded
prices, causing the spread to inflate to increments resembling the
grouping step.
                                                      
  ### Solution                                            
                                                      
  Split the data sources:                             
- Depth/table display: `subscribeToOrderBook` -> `l2Book` with
aggregation params (existing)
- Spread display: `subscribeToPrices(includeOrderBook: true)` -> bbo
feed (new)

The L2Book -> BBO change only affects `subscribeToPrices({
includeOrderBook: true })`, which feeds `usePerpsTopOfBook`. All 5
consumers only need best bid/ask:
                                                      
- Fee calculation (3 views) - compares limit price to best bid/ask for
maker/taker determination
- Bid/Ask presets - single best prices for quick buttons
  - Spread display - bestAsk - bestBid                
                                                      
Full L2Book depth is still used via separate `subscribeToOrderBook()`
path for the order book table/chart.
                                                        
This matches Hyperliquid's frontend: grouping affects the book display,
spread is based on actual top-of-book.
                                                      
  ### Test plan                                           
                                                      
  - Unit tests for processBboData                     
  - Unit tests for BBO subscription lifecycle         
- Unit tests for subscribeToOrderBook (L2Book) - 10 new tests


<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?

AI agent: Be specific about what you changed and why. Include context
about the fix/feature, not generic descriptions.
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)

AI agent: Use format `CHANGELOG entry: [fix/feat/chore]: [User-facing
description in past tense]`.
Examples: `fix: resolved token name display issue`, `feat: added dark
mode toggle`, `chore: updated dependencies`.
For non-user-facing changes, use `CHANGELOG entry: null`.
-->

CHANGELOG entry: Fixed incorrect spread displayed below Perps orderbook
depth chart
## **Related issues**

<!--
AI agent: Replace with `Fixes: #[ISSUE_NUMBER]` using the actual issue
number you're implementing.
-->

Fixes: #25162

## **Manual testing steps**
- Verify spread matches Hyperliquid UI across all grouping values
  - Verify changing grouping doesn't affect spread display

<!--
AI agent: Write specific, contextual Gherkin steps based on what you
actually implemented.
Do NOT use generic placeholders like "my feature name". Be concrete
about the feature, scenario, and steps.
-->

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**
<!-- [screenshots/recordings] -->


https://github.com/user-attachments/assets/43c6c40c-162c-4809-9295-1acaf684d64d


## **Pre-merge author checklist**

<!--
AI agent: Check ALL boxes in this section (mark all as [x]).
-->

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

<!--
AI agent: Leave ALL boxes unchecked ([ ]) - these are for reviewers to
check, not the author.
-->

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Fix spread to match Hyperliquid UI**
> 
> - Switch spread display in `PerpsOrderBookView` to `usePerpsTopOfBook`
(BBO), independent of order book grouping; format via `formatPerpsFiat`
> - Update `HyperLiquidSubscriptionService`: replace `l2Book`-based
top-of-book with singleton `bbo` subscriptions
(`ensureBboSubscription`/`cleanupBboSubscription`), reconnection restore
logic, and cache updates via new `processBboData`
> - Keep full depth via existing `subscribeToOrderBook` (L2Book); add
comprehensive tests for this path plus new BBO lifecycle and processor
tests
> - Adjust tests to mock `usePerpsTopOfBook` and verify spread rendering
and subscription params
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
33d5529. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[6ca25dd](6ca25dd)

Co-authored-by: Matt D. <85914066+geositta@users.noreply.github.com>
…utton fix (#25173)

- style: (cp-7.63.0) trending view browser button fix (#25146)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Effectively reverts this PR:
#24424

From discussion with PM and others:
https://consensys.slack.com/archives/C07NF2K42LE/p1769204088197769
Makes the browser explore icons much more visible.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: style: trending view browser button fix

## **Related issues**

Fixes:
https://consensys.slack.com/archives/C07NF2K42LE/p1769204088197769

## **Manual testing steps**

1. Go to Explore
2. EXPECTED: when no tabs are added, you should see the explore icon.
3. EXPECTED: when tabs are added, you should see the number w/ border.

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

| Theme | No Tabs | Some Tabs |
|--------|--------|--------|
| Dark | <img width="407" height="122" alt="Screenshot 2026-01-26 at 11
29 29"

src="https://github.com/user-attachments/assets/63caddf9-7f65-421f-ae8a-b796d0f908b6"
/> | <img width="398" height="112" alt="Screenshot 2026-01-26 at 11 29
35"

src="https://github.com/user-attachments/assets/5cce5178-6064-460f-a13b-338b061a37a9"
/> |
| Light | <img width="391" height="119" alt="Screenshot 2026-01-26 at 11
29 52"

src="https://github.com/user-attachments/assets/d7842ae5-822a-4903-b868-88fce701709d"
/> | <img width="395" height="114" alt="Screenshot 2026-01-26 at 11 29
59"

src="https://github.com/user-attachments/assets/675c0f2c-1e0c-4364-a510-e531ebec991c"
/> |

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

---
<a

href="https://cursor.com/background-agent?bcId=bc-25940dbd-c3d6-427b-acf8-d8f5d08eaabf"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-cursor-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in
Cursor"
src="https://cursor.com/open-in-cursor.svg"></picture></a>&nbsp;<a

href="https://cursor.com/agents?id=bc-25940dbd-c3d6-427b-acf8-d8f5d08eaabf"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-web-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web"
src="https://cursor.com/open-in-web.svg"></picture></a>


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Improves visibility and clarity of the Explore browser button.
> 
> - In `TrendingView.tsx`, replaces the muted square button with:
>   - A larger `Explore` icon (`IconSize.Xl`) when there are no tabs
> - A compact bordered counter (`h-8 w-8`, `border-2`) showing
`browserTabsCount` when tabs exist
> - Removes unused `IconColor`/`TextColor` imports and associated color
props
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
cd90b4a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[f2a00af](f2a00af)

Co-authored-by: Prithpal Sooriya <prithpal.sooriya@consensys.net>
…o live games (#25171)

- fix(predict): cp-7.63.0 general UI fixes to live games (#25130)

## **Description**

This PR makes UI adjustments to the Predict feature's game markets:

1. **Removed team gradient background** from game market cards and game
details screen - the gradient that used team colors as a background is
no longer needed
2. **Adjusted padding** around the "Your picks" section in game details
- increased top padding from `py-2` to `pt-8` for better visual spacing

### Changes:
- `PredictGameDetailsContent.tsx`: Removed `PredictSportTeamGradient`
wrapper, now uses `SafeAreaView` directly
- `PredictGameDetailsFooter.tsx`: Removed gradient logic and unused
`awayColor`/`homeColor` props
- `PredictMarketSportCard.tsx`: Replaced gradient with simple `Box`
using `bg-muted rounded-xl`
- `PredictPicks.tsx`: Adjusted padding from `py-2` to `pt-8`
- Updated tests and types to reflect the removal of gradient-related
code

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-541

## **Manual testing steps**

```gherkin
Feature: Predict game market UI

  Scenario: User views game market card in feed
    Given the user is on the Predict feed
    When the user views a sports game market card
    Then the card displays with a muted background (no team color gradient)

  Scenario: User views game details screen
    Given the user taps on a sports game market
    When the game details screen opens
    Then the screen displays without a team color gradient background
    And the "Your picks" section has proper spacing from the chart above
```

## **Screenshots/Recordings**

### **Before**

<!-- Team gradient backgrounds visible on cards and details screen -->

### **After**

<!-- Clean muted backgrounds, improved spacing -->
<img width="360" height="760" alt="Screenshot 2026-01-23 at 1 00 33 PM"

src="https://github.com/user-attachments/assets/82a14a45-e491-414f-8ad5-e2af5cf25c2a"
/>
<img width="370" height="764" alt="Screenshot 2026-01-23 at 1 00 18 PM"

src="https://github.com/user-attachments/assets/4879dc50-6a2c-4d71-8e86-03c9b187d3d1"
/>


## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Replaces team color gradients with neutral containers and cleans up
related props/tests.
> 
> - Remove `PredictSportTeamGradient` from `PredictGameDetailsContent`,
`PredictGameDetailsFooter`, and `PredictMarketSportCard`; use
`SafeAreaView`/`Box` with `bg-muted` and rounded corners
> - Drop `awayColor`/`homeColor` props and gradient logic from footer
(`PredictGameDetailsFooter.tsx` and `.types.ts`)
> - Adjust "Your picks" heading spacing in `PredictPicks.tsx` from
`py-2` to `pt-8`
> - Update tests and snapshots to reflect no-gradient UI and removed
props
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
12abe81. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[06a4e3c](06a4e3c)

Co-authored-by: Luis Taniça <matallui@gmail.com>
…-7.63.0 (#25182)

- fix: [Trending tokens] filters overflow cp-7.63.0 (#25175)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
Issue: The filters in the Trending tokens screen are overflowing in
small screen sizes and/or big font sizes.
Solution: I made the filters fit in a horizontal scroll-view, also
maintained UI alignment when the font/size changes to a smaller one

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: fix trending token filters overflowing

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-2545

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**
<img width="591" height="1280" alt="image"

src="https://github.com/user-attachments/assets/901a259b-a448-44fc-943c-13a581b00b29"
/>

<!-- [screenshots/recordings] -->

### **After**



https://github.com/user-attachments/assets/bc67f02c-73ce-41a5-b263-8da4c82ca3f5

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Addresses filter overflow in the Trending Tokens view by making the
control bar horizontally scrollable and refining layout.
> 
> - Wraps the filters control bar in a horizontal `ScrollView` and adds
`controlBarScrollView` styles
> - Tweaks layout styles (`flexGrow: 0`, `minWidth: '100%'`, added
margins/gaps) to maintain alignment and prevent wrapping/overflow
> - Imports `ScrollView`; no changes to sorting/filtering logic or data
flow
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
717bd28. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[1cdf51a](1cdf51a)

Co-authored-by: Juanmi <95381763+juanmigdr@users.noreply.github.com>
… card cp-7.63.0 (#25190)

- fix: [Explore] predict text overflows from card cp-7.63.0 (#25170)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
Issue: Predict text overflows from card when used on explore and the
user has a bigger text size set in their device.
Solution: Added ellipsis when needed

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: fix predict text overflows from card in explore page

## **Related issues**

Fixes:

https://consensyssoftware.atlassian.net/jira/software/c/projects/ASSETS/boards/1567?assignee=712020%3A2d07ba60-e2fc-4bce-b062-89ffccf46204&assignee=unassigned&selectedIssue=ASSETS-2544

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**
<img width="591" height="1280" alt="image"

src="https://github.com/user-attachments/assets/d367b388-1380-466f-b7cf-2af6c815f521"
/>

<!-- [screenshots/recordings] -->

### **After**

<img width="420" height="861" alt="image"

src="https://github.com/user-attachments/assets/cb6eeaa8-2850-458b-9a05-2b790e05ce52"
/>



https://github.com/user-attachments/assets/037f4df2-f083-4434-a5f4-81c1212bf4d3

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Prevents overflow of footer text in `PredictMarketMultiple` by
enforcing single-line truncation and flexible layout.
> 
> - Adds `numberOfLines={1}` and Tailwind styles (`flex-shrink`,
`min-w-0`, `flex-shrink-0`, `ml-2`) to extra outcomes count, total
volume, and recurrence label/icon to enable ellipsis and avoid
wrapping/overlap
> - Minor spacing tweak in the footer container to accommodate
truncation without layout breakage
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c30fbc4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[64241ce](64241ce)

Co-authored-by: Juanmi <95381763+juanmigdr@users.noreply.github.com>
…etail screen cp-7.63.0 (#25203)

- fix: Aggregator guard on perps banner in detail screen cp-7.63.0
(#25078)

## **Description**

**Summary**
Adds token trust validation to the Perps Discovery Banner to prevent it
from appearing on potentially malicious tokens.

**Problem:** The Perps banner was showing based solely on symbol
matching (e.g., "SOL"), which caused it to appear on fake tokens with
matching symbols. This inadvertently lends credibility to scam tokens.
Meaning, a user could open a Perps position from a scam token with the
same symbol as a supported Perp (see recording

**Solution:** Only show the Perps banner for tokens that are either:
- Native tokens (ETH, BNB, SOL, etc.)
- Tokens listed on at least 2 aggregators/exchanges (indicates
legitimacy)

**Changes**
- Added `PERPS_MIN_AGGREGATORS_FOR_TRUST` constant to `perpsConfig.ts`
- Added isTokenTrustworthy check in AssetOverview.tsx
- Added isTokenTrustworthy check in AssetDetails/index.tsx

**Future Improvement**

**Blockaid Integration:** We could trigger a Blockaid scan via
`PhishingController.scanAddress()` when viewing an asset and use the
`tokenScanCache` result to determine if the token is malicious. However,
this approach was deferred because:
- Adds network latency on every asset view
- Increases API resource consumption
- Requires async handling and loading states for the banner

The aggregators-based approach provides an immediate guard with no
additional API calls, covering the majority of scam token cases.
Blockaid integration could be added as a future enhancement for more
comprehensive protection. So, there is still an edge case where scam
tokens can game the aggregators and bypass the aggregator guard.
Blockaid check would solve this edge case.

## **Changelog**

CHANGELOG entry: Add aggregator guard to token detail PerpsBanner

## **Related issues**

Fixes:

## **Manual testing steps**

<!--
AI agent: Write specific, contextual Gherkin steps based on what you
actually implemented.
Do NOT use generic placeholders like "my feature name". Be concrete
about the feature, scenario, and steps.
-->

```gherkin
Feature: Perps Discovery Banner Token Trust Validation
  As a user viewing token details
  I want the Perps trading banner to only appear for legitimate tokens
  So that I am not misled into thinking a scam token is associated with a real Perps market

  Background:
    Given I am logged into MetaMask Mobile
    And the Perps feature flag is enabled
    And I am on a network that supports Perps trading

  Scenario: Banner appears for native tokens with matching Perps market
    Given I navigate to the Asset Overview for native ETH
    And a Perps market exists for "ETH"
    Then I should see the Perps Discovery Banner
    And the banner should display the ETH market leverage

  Scenario: Banner appears for tokens listed on multiple exchanges
    Given I navigate to the Asset Overview for LINK token
    And LINK has 3 aggregators in its token metadata
    And a Perps market exists for "LINK"
    Then I should see the Perps Discovery Banner

  Scenario: Banner does NOT appear for tokens with insufficient aggregators
    Given I navigate to the Asset Overview for a token with symbol "SOL"
    And the token has 0 aggregators in its metadata
    And the token is not a native token
    And a Perps market exists for "SOL"
    Then I should NOT see the Perps Discovery Banner

  Scenario: Banner does NOT appear for fake tokens mimicking native symbols
    Given I navigate to the Asset Overview for a fake "SOL" token on Ethereum
    And the token contract address does not match the real SOL token
    And the token has fewer than 2 aggregators
    Then I should NOT see the Perps Discovery Banner
    Even though a Perps market exists for "SOL"

  Scenario: Banner navigation works correctly for trusted tokens
    Given I navigate to the Asset Overview for native BTC
    And a Perps market exists for "BTC"
    And I see the Perps Discovery Banner
    When I tap on the Perps Discovery Banner
    Then I should be navigated to the BTC Perps Market Details screen
```

## **Screenshots/Recordings**

Before:



https://github.com/user-attachments/assets/97a0f6ab-ab03-4798-a5c8-bfb40734049c

After:



https://github.com/user-attachments/assets/54e75499-84e7-4c9e-9b7f-3a392104bfa8

## **Pre-merge author checklist**

<!--
AI agent: Check ALL boxes in this section (mark all as [x]).
-->

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

<!--
AI agent: Leave ALL boxes unchecked ([ ]) - these are for reviewers to
check, not the author.
-->

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds a token trust guard for the Perps Discovery Banner to avoid
showing it on untrusted tokens.
> 
> - Introduces `PERPS_MIN_AGGREGATORS_FOR_TRUST` and
`isTokenTrustworthyForPerps` in `perpsConfig`
> - Gates `PerpsDiscoveryBanner` in `AssetOverview` and `AssetDetails`
on `isTokenTrustworthy` in addition to existing perps market checks
> - Adds comprehensive tests for trust logic and banner rendering
conditions (`perpsConfig.test.ts`, `AssetOverview.test.tsx`)
> - Minor: `Balance` now passes the full `asset` in navigation params
when opening `AssetDetails`
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1ae8cdd. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[a4a0d88](a4a0d88)

Co-authored-by: Nick Gambino <35090461+gambinish@users.noreply.github.com>
… android cp-7.63.0 (#25191)

- fix: [Explore] search text is invisible on android cp-7.63.0 (#25180)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
Typing any text in the search bar of Explore is not visible on Android,
this PR fixes this by changing the text color so that it is correctly
picked up. Furthermore I have added some top margin for the search bar
since it was too close to the top on android

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: fix text invisible when searching on explore (Android)

## **Related issues**

Fixes: #25115 &
https://consensyssoftware.atlassian.net/browse/ASSETS-2536

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

No placeholder or text can be seen


https://github.com/user-attachments/assets/b39bc0e3-0c3c-4dc5-b2bf-45088364849e


<!-- [screenshots/recordings] -->

### **After**

It looks slow cause my laptop is currently running quite slow


https://github.com/user-attachments/assets/5fba7ec4-b156-4fe6-9940-c1734dd80f0b


<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> - Updates `ExploreSearchBar.tsx` to use `colors.text.muted` for
`placeholderTextColor` and `text-base` input style for clearer search
text rendering.
> - Adds Android-only extra top padding (`+16`) in
`ExploreSearchScreen.tsx` to improve spacing near the status bar.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
14c1616. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[6d470fc](6d470fc)

Co-authored-by: Juanmi <95381763+juanmigdr@users.noreply.github.com>
…5193)

- fix: [Explore] design issues cp-7.63.0 (#25165)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
Solved multiple bugs:
- [Explore] Arrow in subheads should be near titles and remove "View
More". Design is dark screen attached.
- [Explore] Rename "Tokens" to "Trending tokens"
- [Explore] Button corner radius for button row should be 12px, not
16px.
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: solved multiple design issues in trending

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-2540 &
https://consensyssoftware.atlassian.net/browse/ASSETS-2541 &
https://consensyssoftware.atlassian.net/browse/ASSETS-2542

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**



https://github.com/user-attachments/assets/67338a81-72e2-459d-afb9-72ccdd931306


<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Implements design tweaks for Explore/Trending.
> 
> - SectionHeader: header is now a `TouchableOpacity` that triggers
`viewAllAction`; shows title with right arrow; removes separate "View
all" text/button while keeping `testID` prefix
`section-header-view-all-...`
> - Rename "Tokens" to `trending.trending_tokens` ("Trending tokens") in
`sections.config.tsx`, tests, e2e selectors/mappings, and `en.json`
> - QuickActions: change chip style from `rounded-2xl` to `rounded-xl`
(12px)
> - Updated unit/e2e tests and selectors to align with new titles and
header interaction
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d51db76. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[b7e231d](b7e231d)

Co-authored-by: Juanmi <95381763+juanmigdr@users.noreply.github.com>
…rs for Super Bowl (#25208)

- fix(predict): cp-7.63.0 override team colors for Super Bowl (#25204)

## **Description**

Override team colors for Super Bowl teams to ensure correct branding
display. The Polymarket API returns incorrect team colors for the New
England Patriots and Seattle Seahawks, so we apply manual overrides when
caching team data.

**Changes:**
- Added `TEAM_COLOR_OVERRIDES` constant with corrected colors for NE
(Patriots blue) and SEA (Seahawks green)
- Applied color overrides during team cache population

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-545

## **Manual testing steps**

```gherkin
Feature: Predict team colors display

  Scenario: user views Super Bowl market with correct team colors
    Given user has navigated to a Super Bowl prediction market

    When user views the market details
    Then Patriots (NE) should display with color #1D4E9B
    And Seahawks (SEA) should display with color #69BE28
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->
<img width="373" height="772" alt="Screenshot 2026-01-26 at 9 50 42 AM"

src="https://github.com/user-attachments/assets/0e9cde1a-2179-491c-b592-b55ea260ded7"
/>
<img width="367" height="764" alt="Screenshot 2026-01-26 at 9 50 29 AM"

src="https://github.com/user-attachments/assets/5558cf8f-86b9-4fa6-8125-dc85a9c51d7a"
/>




## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Ensures correct branding colors for specific teams when ingesting
Polymarket data.
> 
> - Adds `TEAM_COLOR_OVERRIDES` with NE `#1D4E9B` and SEA `#69BE28`
> - Applies overrides in `TeamsCache.fetchAndCacheTeams` before storing
teams in cache
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4640b44. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[903f214](903f214)

Co-authored-by: Luis Taniça <matallui@gmail.com>
…l event title (#25217)

- fix(predict): cp-7.63.0 override Super Bowl event title (#25206)

## **Description**

Temporarily overrides the title for Super Bowl LX event (ID: 188978) in
Polymarket to display "Super Bowl LX" instead of the original title from
the API.

This is a targeted fix for the Super Bowl event display in the Predict
feature.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-549

## **Manual testing steps**

```gherkin
Feature: Super Bowl event title display

  Scenario: user views Super Bowl LX event
    Given user has access to Predict feature
    And the Polymarket events are loaded

    When user views the Super Bowl LX event (ID: 188978)
    Then the event title displays as "Super Bowl LX"
```

## **Screenshots/Recordings**

### **Before**

N/A

### **After**

<img width="352" height="263" alt="Screenshot 2026-01-26 at 10 55 15 AM"

src="https://github.com/user-attachments/assets/d0d87b23-51d1-4e0f-a0b4-cdec8d8bb793"
/>



## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Ensures correct display of the Super Bowl event name in Predict.
> 
> - In `utils.ts` (`parsePolymarketEvents`), overrides `title` to "Super
Bowl LX" when `event.id === '188978'` (temporary fix)
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7e14b21. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[ffa928d](ffa928d)

Co-authored-by: Luis Taniça <matallui@gmail.com>
…in explore tab (#25224)

- fix(predict): cp-7.63.0 compact game card in explore tab (#25212)

## **Description**

This PR makes the PredictMarketSportCard display a more compact UI when
used in the carousel (Explore tab), consistent with other predict market
card types.

**Changes:**
- Buttons use `ButtonBaseSize.Md` when in carousel mode (making them
smaller/more compact)
- Picks/positions are hidden when in carousel mode (reducing visual
clutter)
- Backward compatible: non-carousel usage remains unchanged

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-543

## **Manual testing steps**

```gherkin
Feature: Compact PredictMarketSportCard in Carousel

  Scenario: User views sport prediction card in Explore carousel
    Given the user is on the Explore tab
    And a sport prediction market is displayed in the carousel

    When user views the PredictMarketSportCard
    Then the buttons should appear at medium size (smaller than normal)
    And no picks/positions should be displayed

  Scenario: User views sport prediction card outside carousel
    Given the user navigates to the Predict feed
    And a sport prediction market is displayed

    When user views the PredictMarketSportCard
    Then the buttons should appear at normal size
    And picks/positions should display if user has any
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->
<img width="368" height="755" alt="Screenshot 2026-01-26 at 11 23 55 AM"

src="https://github.com/user-attachments/assets/17667142-b692-44ee-93a0-f1c835d7d255"
/>


## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Implements a compact layout for Predict sport market cards when
rendered in the Explore carousel.
> 
> - Propagates `isCarousel` through `PredictMarket` →
`PredictMarketSportCard`/`PredictSportCardFooter` →
`PredictActionButtons`/`PredictBetButtons`
> - Sets bet buttons to `ButtonBaseSize.Md` in carousel; hides
picks/positions (`PredictPicksForCard`) when in carousel
> - Adjusts navigation for bet flow when in carousel to route via
`Routes.PREDICT.ROOT` and allows bet buttons even if user has positions
> - Minor UI tweaks: remove vertical margin in carousel and use
`rounded-[16px]` on card container
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
05d578e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[bbffe08](bbffe08)

Co-authored-by: Luis Taniça <matallui@gmail.com>
…wing for claimable positions (#25229)

- fix(predict): cp-7.63.0 game picks not showing for claimable positions
(#25220)

## **Description**

Fixed an issue where positions/picks were not visible for game markets
after the market was closed when users had claimable positions.

**Root Cause:** The `PredictPicks` component was only checking for live
positions when determining whether to render. When a market closed and
positions became claimable (no longer "live"), the component would
return `null` even though there were claimable positions to display.

**Solution:**
1. Added a second `usePredictPositions` hook call with `claimable: true`
to fetch claimable positions
2. Updated render condition to show component when either live OR
claimable positions exist
3. Conditionally hide Cash Out button for claimable positions (since
they can only be claimed, not cashed out)
4. Updated `PredictSportCardFooter` to also render claimable positions

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-551

## **Manual testing steps**

```gherkin
Feature: Game picks display for claimable positions

  Scenario: user views game picks after market closes with claimable positions
    Given user has an open position on a game market
    And the game market has ended and positions are now claimable

    When user navigates to the market details
    Then user sees their position(s) in the "Your picks" section
    And the Cash Out button is not displayed for claimable positions
    And the Claim button is available
```

## **Screenshots/Recordings**

### **Before**

Positions/picks section was hidden when market closed and positions
became claimable.

### **After**

Positions/picks section now displays for both live and claimable
positions, with Cash Out button only shown for non-claimable positions.
<img width="371" height="761" alt="Screenshot 2026-01-26 at 11 57 12 AM"

src="https://github.com/user-attachments/assets/574590a4-1f62-491d-9577-a6f38f4b86d7"
/>
<img width="365" height="766" alt="Screenshot 2026-01-26 at 11 57 02 AM"

src="https://github.com/user-attachments/assets/d0921cba-96d7-45bd-be34-13640ee021b8"
/>



## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Ensures users see their picks after markets close by including
claimable positions alongside live ones and adjusting actions
accordingly.
> 
> - PredictPicks: adds a second `usePredictPositions` call with
`claimable: true`, renders when either `livePositions` or
`claimablePositions` exist, and passes both to `PredictPickItem`; `Cash
out` button is hidden for `claimable` positions
> - PredictSportCardFooter: also fetches `claimablePositions`, renders
them via `PredictPicksForCard`, and shows claim CTA with aggregated
`claimableAmount`
> - Tests: comprehensive unit tests added/updated for live vs claimable
flows, hook parameters, optimistic states, navigation, and action guards
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
afdbf84. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[c560e11](c560e11)

Co-authored-by: Luis Taniça <matallui@gmail.com>
…or accessibility cp-7.63.0 (#25232)

- fix(predict): update Seahawks team color for accessibility cp-7.63.0
(#25230)

## **Description**

Updated the Seattle Seahawks team color from `#69BE28` to `#5BA423` to
improve accessibility. The previous color did not provide sufficient
contrast when used with white text labels, failing accessibility tests.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-545

## **Manual testing steps**

```gherkin
Feature: Predict Team Colors

  Scenario: user views Seahawks team in Predict
    Given user is on a Predict screen showing NFL teams

    When user views a market involving the Seattle Seahawks
    Then the Seahawks team color should display with accessible contrast
    And white text on the Seahawks color background should be readable
```

## **Screenshots/Recordings**

### **Before**

Color: `#69BE28` (lime green - insufficient contrast with white text)

### **After**

Color: `#5BA423` (darker green - meets accessibility contrast
requirements)

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adjusts the Seattle Seahawks team color override to improve contrast.
> 
> - Updates `TEAM_COLOR_OVERRIDES` in `TeamsCache.ts` to change `sea`
from `#69BE28` to `#5BA423`
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
afa83aa. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[7bd5d82](7bd5d82)

Co-authored-by: Luis Taniça <matallui@gmail.com>
….1.0 (#25250)

- fix: cp-7.63.0 bump transaction-pay-controller to 11.1.0 (#25179)

## **Description**

Bumps `@metamask/transaction-pay-controller` from `^11.0.0` to
`^11.1.0`.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: #25113 

## **Manual testing steps**

## **Screenshots/Recordings**

### **Before**

### **After**

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
[ec8b3b8](ec8b3b8)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Updates dependency versions to align with the latest transaction pay
flow.
> 
> - Bumps `@metamask/transaction-pay-controller` to `^11.1.0` in
`package.json`
> - Refreshes `yarn.lock` resolving newer MetaMask controller packages
(e.g., `bridge-controller 64.8.2`, `bridge-status-controller 64.4.4`,
`assets-controllers 96/97`, `keyring-controller 25.1.0`,
`multichain-account-service 5.1.0`, and related
`gas-fee`/`network`/`polling` deps)
> - No application source changes
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d1f24a3. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Matthew Walsh <matthew.walsh@consensys.net>
- fix: rehydration login cp-7.63.0 (#25246)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
The new unlockWallet check for existingUser flag before proceed with
rehydration
since rehydration happen before existing flag is set, it will always not
able to rehydrate when call with unLockWallet.

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: null

## **Related issues**

Fixes:
#25247

## **Manual testing steps**

```gherkin
Feature: Login with rehydration

  Scenario: user login with existing social account
    Given enter password at rehydration screen
 
    Then should unlocked the wallet
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->



https://github.com/user-attachments/assets/da6b051f-d859-4625-9f08-d3256de85d00


### **After**

<!-- [screenshots/recordings] -->



https://github.com/user-attachments/assets/5a313b68-8702-488c-b4a4-789e72b77a5d

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Allows seedless OAuth rehydration to unlock during app start.
> 
> - Updates `unlockWallet` to treat `authPreference.oauth2Login` as an
existing user, attempting unlock even when `existingUser` is not yet set
> - Prevents blocked rehydration flows by deriving/using password and
proceeding with post-login steps
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
54718af. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[732c3e5](732c3e5)

Co-authored-by: ieow <4881057+ieow@users.noreply.github.com>
metamaskbot and others added 27 commits February 3, 2026 16:14
…zation in Deep link event name (#25599)

- fix(analytics): cp-7.63.1 correct capitalization in Deep link event
name (#25592)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

- fix capitalization typo in event name making it invalid agains Segment
Schema

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-319

## **Manual testing steps**

N/A

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk, but this changes the emitted analytics event string, which
could affect downstream dashboards/Segment schema matching until
consumers align on the corrected name.
> 
> **Overview**
> Fixes the deep link consolidated analytics event name capitalization
by changing `DEEP_LINK_USED` from `Deep link Used` to `Deep Link Used`
in `MetaMetrics.events.ts`.
> 
> Updates `DeepLinkModal.test.tsx` mocks to expect the corrected event
name so tests match the new analytics string.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0af7136. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[275dfaf](275dfaf)

Co-authored-by: Nico MASSART <NicolasMassart@users.noreply.github.com>
- fix: Android ANR bug cp-7.64.0 (#25551)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
Fix: Prevent crash caused by Notifee BlockStateBroadcastReceiver during
cold start

## Summary

Fixes a crash that occurs when notification permission changes trigger
Notifee's `BlockStateBroadcastReceiver` before React Native is fully
initialized during app cold start.

## Solution

Disable Notifee's `BlockStateBroadcastReceiver` by adding an override in
`AndroidManifest.xml`. This is the most light weight solution.

Changes (Background Tracking Only):
User Changes Settings OUTSIDE the App
Before (with receiver enabled):
1. User closes MetaMask
2. User goes to Android Settings → Apps → MetaMask → Notifications
3. User toggles "Allow notifications" OFF
4. BlockStateBroadcastReceiver fires immediately
**5. MetaMask knows about the change (while app is closed)**

After (with receiver disabled):
1. User closes MetaMask
2. User goes to Android Settings → Apps → MetaMask → Notifications
3. User toggles "Allow notifications" OFF
4. Nothing happens in the background
**5. MetaMask detects the change next time app opens**

Builds to test:
Crash version:
https://app.bitrise.io/build/f78866d9-cb88-4789-8be0-dec2d7c18e20
Fixed version:

https://app.bitrise.io/build/cd177e81-6545-44ff-a20f-6c5ed11936b5?tab=artifacts

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:Fix: Prevent crash caused by Notifee
BlockStateBroadcastReceiver during cold start

## **Related issues**

Fixes: [Fix: Prevent crash caused by Notifee BlockStateBroadcastReceiver
during cold start
](#25524)

## **Manual testing steps**

```gherkin
Scenario: App launches successfully when notification permission is disabled in Android Settings during cold start (After Fix)
  Given the MetaMask app is completely closed
  When I open Android Settings
  And I navigate to "Apps" → "MetaMask" → "Notifications"
  And I toggle "Allow notifications" to OFF
  And I return to the home screen
  And I tap the MetaMask app icon to launch it
  Then the app should launch successfully
  And I should not see any crash dialogs
  And I should see the wallet home screen
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**


![crashed](https://github.com/user-attachments/assets/5031a720-dec4-4b4a-9daa-3fc0f19a9847)

### **After**
![no

crash](https://github.com/user-attachments/assets/7be5a943-e477-4379-8678-994584e116a6)


<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk manifest-only change; main impact is disabling Notifee’s
background receiver so notification permission toggles won’t be detected
until next app launch.
> 
> **Overview**
> Prevents a cold-start crash/ANR by disabling Notifee’s
`app.notifee.core.BlockStateBroadcastReceiver` via an
`AndroidManifest.xml` override.
> 
> This removes the receiver from the merged manifest (and marks it
`enabled="false"`), trading off background detection of Android
notification permission changes while the app is closed for startup
stability.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e00915c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
[b566864](b566864)

Co-authored-by: Wei Sun <wei.sun@consensys.net>
Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
This PR updates the change log for 7.63.1. (Hotfix - no test plan
generated.)

---------

Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Mirror [extension E2E
test](https://github.com/MetaMask/metamask-extension/blob/main/test/e2e/snaps/test-snap-ethereum-provider.spec.ts#L75-L96)
by checking against genesis hashes instead of chain IDs when validating
that the Snap can switch the network correctly.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: null

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk because changes are limited to E2E test assertions/selectors
and add deterministic RPC mocking; no production logic is modified.
> 
> **Overview**
> Updates the `test-snap-ethereum-provider` E2E to validate network
switching by requesting the genesis block and asserting its hash for
Ethereum, Linea, and Sepolia (using `checkResultSpanIncludes`) rather
than asserting `chainId`.
> 
> Adds a new `getGenesisHashButton` selector and wires in
`mockGenesisBlocks` during fixture setup so tests don’t depend on live
RPC responses.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a155d88. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…atterns (#25549)

## **Description**

This PR adds and improves test coverage for the "Copied Address"
analytics event to ensure proper tracking of user behavior when copying
addresses across different locations in the app.

**What is the reason for the change?**
We need to track where users are copying addresses from to understand
their patterns and improve UX. The analytics tracking was implemented
but lacked comprehensive test coverage.

**What is the improvement/solution?**
- Fixed failing tests in AddressList component for the
WALLET_COPIED_ADDRESS event
- Added comprehensive test coverage for AddressField component's copy
functionality
- Ensured all tests verify correct event properties including `location`
and `chain_id` metadata

Schema PR: Consensys/segment-schema#443

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-299

## **Manual testing steps**

```gherkin
Feature: Copied Address Analytics Event

  Scenario: user copies address from address list
    Given user is on the address list screen
    When user presses the copy button on an address
    Then WALLET_COPIED_ADDRESS event is tracked with location "address-list" and chain_id
    
   Scenario: user copies address from share qr screen
    Given user is on the address list screen
    Then goes to the QR share screen
    When user presses the copy button on an address
    Then WALLET_COPIED_ADDRESS event is tracked with location "qr-scan" and chain_id

  Scenario: user copies address from notification details
    Given user is viewing notification details with an address field
    When user presses the copy button on the address
    Then WALLET_COPIED_ADDRESS event is tracked with location "notification-details"
```

## **Screenshots/Recordings**

`~`

### **Before**

`~`

### **After**

`~`

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: adds MetaMetrics instrumentation on existing copy actions
and expands unit tests; behavior change is limited to emitting analytics
and a new `testID` on the notification address copy pressable.
> 
> **Overview**
> Adds a new MetaMetrics event `EVENT_NAME.ADDRESS_COPIED` and
instruments address copy actions to emit it with a `location` (and
`chain_id_caip` where available).
> 
> Copy tracking is added/updated for multichain `AddressList` (includes
CAIP chain id), `QRAccountDisplay` (new optional
`analyticsLocation`/`chainId` props; wired from `ShareAddress` and
`ShareAddressQR`), and the notifications `AddressField` (adds `testID`
and tracks from `notification-details`).
> 
> Extends/updates unit tests to assert the event builder/`trackEvent`
calls and properties across these surfaces.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6548ec5. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Strengthens E2E tag dependency definitions for the AI test selector.

## Changes

- **Stronger language**: Changed "consider" → "also select" in tag
descriptions for explicit dependencies
- **Added missing dependencies**: SmokePerps/SmokePredictions/SmokeCard
now include SmokeConfirmations (on-chain transactions)
- **Simplified closing prompt**: References tag descriptions


<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: changes are limited to E2E AI analyzer docs/prompts and
smoke tag description text, affecting test selection guidance but not
app runtime behavior.
> 
> **Overview**
> Makes **smoke tag dependency guidance explicit** in `e2e/tags.js`
(e.g., Trade/NetworkExpansion/Accounts/Identity/NetworkAbstractions now
call out when to *also select* dependent tags like `SmokeConfirmations`,
`SmokeWalletPlatform`, `SmokeMultiChainAPI`).
> 
> Updates the E2E AI analyzer docs
(`tests/tools/e2e-ai-analyzer/README.md`) with clearer local run
commands and notes about CI outputs, and adjusts the `select-tags` task
prompt to **require verifying dependent tags** before finalizing
selection.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b8659de. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…25641)

## **Description**

The "Change" text in the PaymentMethodSelector component on the Buy
screen was hardcoded in English. This PR adds proper localization
support by:

1. Adding a new i18n key `fiat_on_ramp_aggregator.payment_method.change`
in `en.json`
2. Updating `PaymentMethodSelector.tsx` to use the `strings()` function
instead of the hardcoded text

This allows the text to be translated into other languages.

## **Changelog**

CHANGELOG entry: Fixed missing localization for "Change" text on the Buy
screen

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-3255

## **Manual testing steps**

```gherkin
Feature: Localized Change text on Buy screen

  Scenario: User sees localized Change text
    Given the user has the app set to a non-English locale
    And the user navigates to the Buy screen

    When user views the payment method selector
    Then the "Change" text should be displayed in the user's locale (once translations are added)
```

## **Screenshots/Recordings**

### **Before**

Hardcoded "Change" text in English regardless of locale.

### **After**

"Change" text now uses i18n `strings()` function and can be translated.

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk UI-only change: replaces a hardcoded string with an i18n
lookup and adds the corresponding English translation key.
> 
> **Overview**
> Removes the hardcoded "Change" label in `PaymentMethodSelector` and
sources it from
`strings('fiat_on_ramp_aggregator.payment_method.change')` instead.
> 
> Adds the new `fiat_on_ramp_aggregator.payment_method.change` entry to
`en.json` to support localization.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
bbd2704. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
Summary of changes
1. Slack: Improved failure messages
2. Tagging dev team responsible per failed test
Failed tests:
@Accounts-team:
Import SRP with +50 accounts, SRP 1, SRP 2, SRP 3 - Test error → Failed
on Android & iOS: <Recording (Android)> · <Recording (iOS)>
@team-predict:
Predict Deposit - Complete Flow Performance - Test error → Failed on
Android & iOS: Recording (session: 3589404d…) · <Recording (iOS)>
Predict Market Details - Load Time Performance - Test timed out → Failed
on iOS: —
@mm-perps-engineering-team:
Perps open position and close it - Test error → Failed on Android & iOS:
<Recording (Android)> · <Recording (iOS)>
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
3. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches the Appwright reporting/aggregation pipeline and Slack message
generation, which can affect CI pass/fail signals and notifications even
though it’s test-only code.
> 
> **Overview**
> Adds *team ownership tagging* to Appwright performance tests and
propagates that metadata through metrics/session attachments so reports
can attribute results to a responsible team.
> 
> Enhances the custom reporter and aggregation/scripts to include
`team`, `tags`, and `testFilePath`, generate a
`failed-tests-by-team.json`, and produce a richer Slack summary that
groups unique failing tests by team (including quality-gate failures and
recording links) while treating tests as failed only if all retries
fail.
> 
> Includes a few reliability tweaks: conditional Outcomes-tab timing for
Predict market details, improved tab selectors in
`PredictDetailsScreen`, a BrowserStack recording URL fallback,
device-info recovery from profiling metadata, minor threshold/timeout
adjustments, and removal of an unused `BridgeScreen` selector.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
44a136f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
Following #24313 we're
looking to centralize all tools and test resources in one place.
This PR moves spec files for `Confrimations` to `/tests`.

Previous related PRs:
- #24988
- #24313
- #25031
- #25095
- #25167
- #25198
- #25219
- #25263
- #25279
- #25520
- #25533
- #25598


<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MMQA-1235

## **Manual testing steps**
N/A

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**
N/A
<!-- [screenshots/recordings] -->

### **After**
N/A
<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Test-only refactor that mainly rewires import paths and
fixture/resource locations; risk is limited to breaking e2e/smoke test
execution due to incorrect paths or module resolution.
> 
> **Overview**
> Centralizes Confirmations e2e specs under `tests/` by updating
smoke/regression specs to import shared tooling from the new
`tests/framework`, `tests/api-mocking`, `tests/seeder`, and `e2e/pages`
locations.
> 
> Updates Anvil/local-node fixtures to load the EIP-7702 delegator state
from the new
`./tests/smoke/confirmations/transactions/7702/withDelegatorContracts.json`
path, and adjusts supporting helpers (e.g., analytics/metrics
validation) to the new module layout.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a800be4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
# 🚀 v7.63.1 Testing & Release Quality Process

Hi Team,  
As part of our new **MetaMask Release Quality Process**, here’s a quick
overview of the key processes, testing strategies, and milestones to
ensure a smooth and high-quality deployment.

---

## 📋 Key Processes

### Testing Strategy
- **Developer Teams:**  
Conduct regression and exploratory testing for your functional areas,
including automated and manual tests for critical workflows.
- **QA Team:**  
Focus on exploratory testing across the wallet, prioritize high-impact
areas, and triage any Sentry errors found during testing.
- **Customer Success Team:**  
Validate new functionalities and provide feedback to support release
monitoring.

### GitHub Signoff
- Each team must **sign off on the Release Candidate (RC)** via GitHub
by the end of the validation timeline (**Tuesday EOD PT**).
- Ensure all tests outlined in the Testing Plan are executed, and any
identified issues are addressed.

### Issue Resolution
- **Resolve all Release Blockers** (Sev0 and Sev1) by **Tuesday EOD
PT**.
- For unresolved blockers, PRs may be reverted, or feature flags
disabled to maintain release quality and timelines.

### Cherry-Picking Criteria
- Only **critical fixes** meeting outlined criteria will be
cherry-picked.
- Developers must ensure these fixes are thoroughly reviewed, tested,
and merged by **Tuesday EOD PT**.

---

## 🗓️ Timeline and Milestones

1. **Today (Friday):** Begin Release Candidate validation.  
2. **Tuesday EOD PT:** Finalize RC with all fixes and cherry-picks.  
3. **Wednesday:** Buffer day for final checks.  
4. **Thursday:** Submit release to app stores and begin rollout to 1% of
users.
5. **Monday:** Scale deployment to 10%.  
6. **Tuesday:** Full rollout to 100%.

---

## ✅ Signoff Checklist

Each team is responsible for signing off via GitHub. Use the checkbox
below to track signoff completion:

# Team sign-off checklist
- [ ] Mobile Platform

This process is a major step forward in ensuring release stability and
quality. Let’s stay aligned and make this release a success! 🚀

Feel free to reach out if you have questions or need clarification. 

Many thanks in advance

# Reference
- Testing plan sheet -
https://docs.google.com/spreadsheets/d/1tsoodlAlyvEUpkkcNcbZ4PM9HuC9cEM80RZeoVv5OCQ/edit?gid=404070372#gid=404070372
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Updates the mobile app to consume the new RampsController state shape.
Ramps state is now organized as nested `ResourceState` objects per
resource, so each resource exposes `data`, `selected`, `isLoading`, and
`error` from a single selector. This removes the need for separate
request selectors and flat `selected*` properties when reading ramps
state.

## Motivation

- **Single selector per resource** – Consumers no longer need to build
cache keys or use `select*Request` to get loading/error; they come from
the same selector as the data.
- **Consistent API** – All ramps resources (userRegion, countries,
providers, tokens, paymentMethods, quotes) use the same
`ResourceState<TData, TSelected>` shape.
- **Simpler hooks** – Hooks destructure `{ data, selected, isLoading,
error }` from one `useSelector(selectX)` call instead of combining
multiple selectors.

## Changes

### Selectors (`app/selectors/rampsController/index.ts`)

- **Resource selectors** now return a `ResourceState` object:
- `selectUserRegion` → `{ data, selected, isLoading, error }` (no
`selected` for user region)
  - `selectCountries` → `{ data, selected, isLoading, error }`
  - `selectProviders` → `{ data, selected, isLoading, error }`
  - `selectTokens` → `{ data, selected, isLoading, error }`
  - `selectPaymentMethods` → `{ data, selected, isLoading, error }`
  - `selectQuotes` → `{ data, selected, isLoading, error }`
- **Flat selected selectors** (`selectSelectedProvider`,
`selectSelectedToken`, `selectSelectedPaymentMethod`) are deprecated in
favor of reading `selected` from the corresponding resource selector.
They remain for backward compatibility but read from the old flat state
shape.
- **Request selectors** (`selectUserRegionRequest`,
`selectCountriesRequest`, `selectTokensRequest`,
`selectProvidersRequest`, `selectPaymentMethodsRequest`) remain for any
code that still needs request-key–scoped state; primary loading/error
for a resource should be taken from the resource selector’s `isLoading`
and `error`.

### Hooks

- **`useRampsUserRegion`** – Uses `useSelector(selectUserRegion)` and
returns `{ userRegion, isLoading, error, fetchUserRegion, setUserRegion
}` where `userRegion` is `data` from the resource state.
- **`useRampsCountries`** – Uses `useSelector(selectCountries)` and
returns `{ countries, isLoading, error }` with `countries` from `data`.
- **`useRampsProviders`** – Uses `useSelector(selectProviders)` and
returns `{ providers, selectedProvider, setSelectedProvider, isLoading,
error }` with `providers` from `data` and `selectedProvider` from
`selected`.
- **`useRampsTokens`** – Uses `useSelector(selectTokens)` and returns `{
tokens, selectedToken, setSelectedToken, isLoading, error }` with
`tokens` from `data` and `selectedToken` from `selected`.
- **`useRampsPaymentMethods`** – Uses
`useSelector(selectPaymentMethods)` and returns `{ paymentMethods,
selectedPaymentMethod, setSelectedPaymentMethod, isLoading, error }`
with `paymentMethods` from `data` and `selectedPaymentMethod` from
`selected`.
- **`useHydrateRampsController`** – Uses `selectUserRegion` and reads
`userRegion` from `data` (e.g. `userRegion.data?.regionCode`) to decide
when to run hydration.

### Tests

- RampsController selector tests updated to the new nested state: mock
state uses `createDefaultResourceState` for each resource, and
assertions expect the `ResourceState` shape (e.g. `result.data`,
`result.selected`, `result.isLoading`, `result.error`).

## Migration (before / after)

**Before (multiple selectors and request key):**

```ts
const requestSelector = useMemo(
  () =>
    selectPaymentMethodsRequest({
      region,
      action,
      paymentMethodCurrency,
      /* ... */
    }),
  [region, action, paymentMethodCurrency, /* ... */]
);
const { isLoading, error } = useSelector(requestSelector);
const paymentMethods = useSelector(selectPaymentMethods);
const selectedPaymentMethod = useSelector(selectSelectedPaymentMethod);
```

**After (single resource selector):**

```ts
const {
  data: paymentMethods,
  selected: selectedPaymentMethod,
  isLoading,
  error,
} = useSelector(selectPaymentMethods);
```

## New state shape (reference)

```ts
interface ResourceState<TData, TSelected = null> {
  data: TData;
  selected: TSelected;
  isLoading: boolean;
  error: string | null;
}

interface RampsControllerState {
  userRegion: ResourceState<UserRegion | null>;
  countries: ResourceState<Country[]>;
  providers: ResourceState<Provider[], Provider | null>;
  tokens: ResourceState<TokensResponse | null, RampsToken | null>;
  paymentMethods: ResourceState<PaymentMethod[], PaymentMethod | null>;
  quotes: ResourceState<QuotesResponse | null>;
  requests: RequestsState;
}
```

## Breaking changes

- All ramps **resource** selectors now return a `ResourceState` object
(`data`, `selected`, `isLoading`, `error`) instead of raw data or flat
loading/error.
- Any component or hook that used `selectUserRegion`, `selectCountries`,
`selectProviders`, `selectTokens`, `selectPaymentMethods`, or
`selectQuotes` and expected the previous return type must destructure
`.data` (and optionally `.selected`, `.isLoading`, `.error`) from the
selector result.
- Prefer reading `selected` from the resource selector (e.g.
`selectPaymentMethods(state).selected`) instead of
`selectSelectedPaymentMethod(state)` for consistency with the new shape.

## Dependencies

- Requires the corresponding RampsController (core) update that
introduces the nested `ResourceState` and removes flat `selected*` and
per-resource loading/error fields from state.


<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**
V2 DISABLED
https://www.loom.com/share/a7f356caa0e3400890cd2261c1ed9d96


<!-- [screenshots/recordings] -->

### **After**

V2 ENABLED
https://www.loom.com/share/14c6a5ef12e841608557c3e9242aeb27

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **High Risk**
> High risk because it changes the persisted `RampsController` Redux
state shape (and adds a new migration) and updates selectors/hooks
accordingly; any missed consumer can break ramps flows or state
hydration on upgrade.
> 
> **Overview**
> Updates the app to consume `@metamask/ramps-controller@6` by switching
ramps resources (`providers`, `tokens`, `countries`, `paymentMethods`,
`quotes`) to nested `ResourceState` selectors (`{ data, selected,
isLoading, error }`) and simplifying ramps hooks to read from those
selectors instead of request-key selectors/flat `selected*` fields.
> 
> Removes `useRampsController` options and strips `useRampsUserRegion`
down to `userRegion` + `setUserRegion` (no
`fetchUserRegion`/loading/error), then updates affected UI tests/mocks
and state fixtures/snapshots to match the new nested state.
> 
> Adds migration `117` (wired into migrations index) to convert legacy
persisted ramps state (arrays/flat `selected*` and nullable
`tokens`/`quotes`) into `ResourceState` objects and to delete deprecated
top-level `selectedProvider`/`selectedToken`/`selectedPaymentMethod`;
also updates `useRampNavigation` so V2 buy-routing sets the selected
token before navigating to `BuildQuote`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f24abad. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

Context
Gas sponsorship on certain networks (like Monad) has reserve balance
requirements. When a transaction simulation fails due to reserve balance
violations, users currently don't receive clear feedback about why
sponsorship isn't available.

Problem
Users on networks with gas sponsorship reserve requirements (e.g., Monad
requires 10 MON minimum) don't see any warning when their transaction
can't be sponsored due to insufficient reserve balance.

Solution
Added a new useGasSponsorshipWarningAlerts hook that:
Checks simulationData.callTraceErrors for known sponsorship failure
patterns
Uses a configurable rules system (GAS_SPONSORSHIP_WARNING_RULES) to
match chain-specific error patterns
Displays a Severity.Warning alert on the EstimatedFee row when
sponsorship fails due to reserve balance violations
Currently configured for Monad (10 MON minimum reserve requirement)

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: Added a warning message when gas sponsorship is
unavailable due to reserve balance requirements.

## **Related issues**

Fixes:
https://consensyssoftware.atlassian.net/jira/software/c/projects/NEB/boards/3738?assignee=62710850d7fd480068d7cff9&selectedIssue=NEB-11

## **Manual testing steps**

Pre-requisite:
Use the dev sentinel API in:

In app/util/transactions/sentinel-api.ts: const BASE_URL =
'https://tx-sentinel-{0}.dev-api.cx.metamask.io/';
In
node_modules/@metamask/transaction-controller/dist/api/simulation-api.cjs:
const BASE_URL = 'https://tx-sentinel-{0}.dev-api.cx.metamask.io/';

1 - Connect to Monad
2 - Ensure account has less than 10 MON balance
3 - Initiate a transaction by sending some MON to another address
4 - Observe the warning alert on the confirmation screen stating "Gas
sponsorship isn't available for this transaction. You'll need to keep at
least 10 MON in your account."

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->
<img width="364" height="809" alt="image"
src="https://github.com/user-attachments/assets/94ffeb6f-04be-4848-ab3a-aa73ac94c8ab"
/>


## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds new confirmation alert logic driven by simulation
`callTraceErrors` and bumps the patched
`@metamask/transaction-controller` to `62.10.0`, which pulls in updated
controller dependencies. Risk is mainly around behavior changes from the
dependency update and potential false positives/negatives when matching
error strings.
> 
> **Overview**
> Adds a new `useGasSponsorshipWarningAlert` that inspects simulation
`callTraceErrors` and, when gasless is supported but sponsorship is not
applied, surfaces a **non-blocking warning** on the confirmation
`EstimatedFee` row (currently matching Monad “reserve balance violation”
with a 10 MON minimum).
> 
> Wires this alert into `useConfirmationAlerts`, metrics
(`useConfirmationAlertMetrics`), and i18n (`en.json`), with dedicated
unit tests.
> 
> Updates the patched `@metamask/transaction-controller` from `62.9.0`
to `62.10.0` (new patch file) and refreshes `yarn.lock` accordingly.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7564504. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…rk to "Popular networks" EVM tokens aren't displayed (#25630)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
Bug: When I switch the network filter from a non-EVM network to "Popular
networks" my EVM tokens aren't displayed.

Solution: I have idnetified that this bug was introduced by
[this](#25468) PR and
needs to be backported cause the bug was also backported
[here](#25580)

The issue is that the wrong selector `selectSelectedInternalAccountId`
was being used instead of `selectSelectedInternalAccountByScope`

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: fix when switching the network filter from a non-EVM
network to "Popular networks" EVM tokens aren't displayed

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-2597 &
#25632

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**


https://github.com/user-attachments/assets/bcffcb65-3227-467d-9255-55d2177f2416


<!-- [screenshots/recordings] -->

### **After**


https://github.com/user-attachments/assets/b0e5a877-b7ae-4078-a0fa-d4000a9525f6


<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes core asset-selection logic used to render token/native/staked
balances across networks; a mistake could hide or mis-associate assets
when switching networks/account groups.
> 
> **Overview**
> Fixes an asset lookup bug where switching from a non-EVM network
filter back to EVM (“Popular networks”) could return the wrong/missing
EVM token entries.
> 
> `selectAsset` now scopes native/staked and token lookups to the
*selected account group’s* account for the requested chain via
`selectSelectedInternalAccountByScope`, normalizing chain IDs to CAIP
with `isCaipChainId`/`toEvmCaipChainId` instead of relying on
`selectSelectedInternalAccountId`.
> 
> Updates `assets-list.test.ts` to validate scoping by account group
(adding a second group/account and asserting balances switch correctly).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6c68b7c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
This PR syncs the stable branch to main for version 7.65.0.

*Synchronization Process:*

- Fetches the latest changes from the remote repository
- Resets the branch to match the stable branch
- Attempts to merge changes from main into the branch
- Handles merge conflicts if they occur

*File Preservation:*

Preserves specific files from the stable branch:
  - CHANGELOG.md
  - bitrise.yml
  - android/app/build.gradle
  - ios/MetaMask.xcodeproj/project.pbxproj
  - package.json

  Indicates the next version candidate of main to 7.65.0

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Changelog-only update with no runtime code changes; risk is limited to
potential version/link bookkeeping errors.
> 
> **Overview**
> Updates `CHANGELOG.md` by adding new sections for **`7.63.0`**
(Added/Fixed items) and **`7.63.1`** (Fixed items).
> 
> Also updates the compare links at the bottom so `[Unreleased]` now
compares from `v7.63.1`, and adds new link entries for `7.63.0` and
`7.63.1`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f2c2e40. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Refactors PerpsController services to use the messenger pattern for
inter-controller communication instead of direct controller access via
`PerpsPlatformDependencies.controllers`.

**Why:**
- Aligns with MetaMask's standard controller architecture pattern
- Decouples services from direct controller dependencies
- Makes dependencies explicit and testable through messenger actions
- Improves type safety with typed messenger actions

**What changed:**

### Messenger Pattern Migration
- Services now receive a `PerpsControllerMessenger` via constructor
injection
- Replaced `controllers.accounts.getSelectedEvmAccount()` with
`messenger.call('AccountsController:getSelectedAccount')`
- Replaced `controllers.keyring.signTypedMessage()` with
`messenger.call('KeyringController:signTypedMessage')`
- Replaced `controllers.authentication.getBearerToken()` with
`messenger.call('AuthenticationController:getBearerToken')`
- Replaced `controllers.network.*` with
`messenger.call('NetworkController:findNetworkClientIdByChainId')`
- Replaced `controllers.transaction.submit()` with
`messenger.call('TransactionController:addTransaction')`
- Removed `controllers` section from `PerpsPlatformDependencies`
interface
- Removed obsolete controller interfaces from types
(`PerpsKeyringController`, `PerpsAccountUtils`,
`PerpsNetworkOperations`, `PerpsTransactionOperations`)

### Code Quality Improvements
- **SCREAMING_CASE constants**: Renamed `PerpsEventProperties` →
`PERPS_EVENT_PROPERTY` and `PerpsEventValues` → `PERPS_EVENT_VALUE` to
follow JS/TS naming conventions (~25+ files updated)
- **Consistent error handling**: Added `ensureError()` wrapper in catch
blocks for type-safe error logging across services and hooks

### Test Updates
- Updated all test files to use `createMockMessenger()` helper
- Fixed test files (`PerpsController.test.ts`,
`HyperLiquidProvider.test.ts`) to mock messenger actions instead of
removed infrastructure controllers

**Note:** Using `AccountsController:getSelectedAccount` is semantically
equivalent to the previous approach of
`AccountTreeController.getAccountsFromSelectedAccountGroup()` +
`findEvmAccount()` because
`AccountTreeController.setSelectedAccountGroup()` automatically updates
`AccountsController.selectedAccount` to the EVM account from that group.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: N/A (internal refactor)

## **Manual testing steps**

```gherkin
Feature: Perps Controller Messenger Pattern

  Scenario: User can still perform perps operations after refactor
    Given the user has a perps-enabled account

    When user opens the perps trading interface
    Then the account state loads correctly

    When user places a market order
    Then the order is signed and submitted successfully

    When user initiates a deposit
    Then the deposit transaction is prepared with correct account
```

## **Screenshots/Recordings**

N/A - Internal refactor with no UI changes

### **Before**

N/A

### **After**

Still working as expected.


https://github.com/user-attachments/assets/a2bdbe03-07c5-4f09-9d62-4a1908cb230a



## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Broad refactor across Perps controller/UI analytics and transaction
submission paths; regressions could impact trading/deposit flows or
analytics payload consistency.
> 
> **Overview**
> Refactors Perps controller/service integrations to **use
messenger-based inter-controller calls** (e.g., network lookup and
`TransactionController:addTransaction`) and simplifies the mobile
infrastructure adapter by removing consolidated `controllers.*` access.
> 
> Standardizes Perps analytics constants by renaming
`PerpsEventProperties/PerpsEventValues` to
`PERPS_EVENT_PROPERTY/PERPS_EVENT_VALUE` across Perps
UI/components/tests, and tightens error logging in Perps views/debug
tooling via `ensureError()`.
> 
> Updates Perps test utilities/mocks to match the new architecture (adds
`createMockMessenger`, expands stream manager mock with
`clearAllChannels`) and adjusts `PerpsController`
deposit-with-confirmation tests to mock messenger actions instead of
direct controller adapters.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ceb79c6. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

This unblocks this issue
#25474

The underlying issue is that the remote feature flag controller does not
reset cache on version upgrades, so users will need to close their app
and wait for the feature flag cache to expire before they can see the
new feature.

However the remote feature flag controller change would be pretty large,
so to keep the scope small (and because the explore feature is released)
we will be hardcoding the feature flag to true.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: fix: default explore feature to enabled

## **Related issues**

Fixes: #25474

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

https://www.loom.com/share/a9112c646381436898a7bcd63c7ab028

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

---
<a
href="https://cursor.com/background-agent?bcId=bc-6a60576f-64a8-447f-843a-6d9be5062f1d"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-6a60576f-64a8-447f-843a-6d9be5062f1d"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>




<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Forces a feature flag to default-on for most builds, which can
unintentionally enable UI/flows for users regardless of remote rollout
state; limited scope but impacts runtime behavior. E2E behavior is
explicitly preserved via `isE2E` gating.
> 
> **Overview**
> **Defaults the Explore/Trending Tokens feature to enabled** by
injecting a selector-level override: `selectAssetsTrendingTokensEnabled`
now forces the env override to `'true'` for non-E2E builds, bypassing
remote-flag caching/version rollout delays.
> 
> Updates tests to mock `isE2E` and refreshes `MainNavigator` snapshots
to include the `ExploreSearch`, `SitesFullView`, and `BrowserTabHome`
routes.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
eaed767. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes how Trending/Explore sections are derived and rendered based
on the `selectPerpsEnabledFlag`, which can affect section
ordering/visibility across the feed, quick actions, and search. Risk is
mainly UI/behavioral (gating + memoization dependencies), not security-
or data-critical.
> 
> **Overview**
> **Conditionally removes the `perps` section from Trending/Explore UI
when the Perps feature flag is disabled.** `sections.config.tsx` now
exposes `useHomeSections` and `useSectionsArray` hooks that filter
`HOME_SECTIONS_ARRAY`/`SECTIONS_ARRAY` based on
`selectPerpsEnabledFlag`.
> 
> Trending feed rendering (`TrendingView.tsx`), quick actions
(`QuickActions.tsx`), and explore search ordering/processing
(`useExploreSearch.ts`) were updated to use these new hooks instead of
the static exported arrays, and tests were adjusted to mock
`useSectionsArray` accordingly.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f708e4c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…25563)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

This removes the `userLoggedIn` conditional route definition in the
navigation stack, which resolves a race condition associated with the
re-rendering of the stack. It caused users to be stuck on the LockScreen
post manual lock.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:

## **Related issues**

Fixes: #25560 

## **Manual testing steps**

- Manually lock the app from settings
- Should land on the Login screen, not stuck on the Lock screen

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->


https://github.com/user-attachments/assets/4c85e502-6b3c-47d0-a37b-940a5165beed


### **After**

<!-- [screenshots/recordings] -->


https://github.com/user-attachments/assets/24ebda8e-0da9-4169-a16b-9756cf48e634


## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes the root navigation stack to always define the `HOME_NAV`
screen, which could impact locked/unlocked access flows if other guards
are insufficient. Primary risk is unintended navigation to `Main` during
edge-case lock/unlock transitions or deep links.
> 
> **Overview**
> Removes the `userLoggedIn`-gated route definition for
`Routes.ONBOARDING.HOME_NAV` in `AppFlow`, so the `Main` navigator is
always registered in the root stack.
> 
> This eliminates the `selectUserLoggedIn` dependency and avoids stack
re-definition/re-render behavior that could leave users stuck after
manually locking.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
cd7849d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

This PR fixes an issue where the `updateTokenAmountCallback` effect was
not being awaited in `transactionPayData.sourceAmounts`, which was
preventing the `mm_pay_quote_requested` metric from being set correctly.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:

## **Related issues**

Fixes: MetaMask/MetaMask-planning#6966

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [X] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [X] I've completed the PR template to the best of my ability
- [X] I've included tests if applicable
- [X] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [X] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: scoped to confirmation metrics timing in
`useTransactionCustomAmount` and updates a unit test to match; no
transaction execution logic changes.
> 
> **Overview**
> Adjusts `useTransactionCustomAmount` so `mm_pay_quote_requested` is
**not** emitted immediately on `updateTokenAmount()`, but only once
`hasSourceAmount` becomes true after a token-amount update (tracked via
a new `isTokenAmountUpdated` flag).
> 
> Updates the related hook test to assert the metric fires on a
subsequent rerender when `hasSourceAmount` flips from false to true.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
00513dd. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…cp-7.64.0 (#25569)

## **Description**

This PR improves the Perps WebSocket connection toast (the banner that
shows "Your connection is offline", "Connecting...", or "Connected" when
the WebSocket state changes).

## **Changelog**

CHANGELOG entry: Added swipe-to-dismiss and 1 second delay for the Perps
connection banner; improved toast styling with default/muted backgrounds
and highest z-index.

## **Related issues**

Fixes: #25570
Jira issue: https://consensyssoftware.atlassian.net/browse/TAT-2453

## **Manual testing steps**

```gherkin
Feature: Perps connection toast

  Scenario: user sees and dismisses offline banner
    Given user is on a screen where Perps WebSocket is connected
    When connection drops and 1 second passes
    Then the "Your connection is offline" banner appears at the top
    And user can swipe the banner left or right to dismiss it
    And after dismissing, the banner does not show again until connection is restored and drops again

  Scenario: banner does not flicker on quick reconnect
    Given user is on a screen where Perps WebSocket is connected
    When connection drops and reconnects within 1 second
    Then the offline banner does not appear

```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

See here https://consensyssoftware.atlassian.net/browse/TAT-2453

### **After**

<!-- [screenshots/recordings] -->
<img width="1206" height="2622" alt="Simulator Screenshot - iPhone 17
Pro - 2026-02-03 at 11 39 17"
src="https://github.com/user-attachments/assets/8656ba68-5dd3-4584-bae0-765aa60e1f51"
/>


## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes toast timing and suppression logic around WebSocket
disconnect/reconnect events, which could inadvertently hide or delay
offline/connecting signals. Scope is limited to Perps connection banner
UI/state with updated test coverage.
> 
> **Overview**
> Improves the Perps WebSocket connection toast UX by adding
**horizontal swipe-to-dismiss** and tracking a `userDismissed` state so
repeat *Disconnected* banners are suppressed until the connection
restores.
> 
> Adds a **1s delay** before showing *Disconnected/Connecting* banners
(and cancels pending banners on quick reconnect) to reduce flicker,
while still showing the *Connected* success toast immediately.
> 
> Updates toast styling to use a `toastWrapper` with default background
+ shadow and a muted inner surface, and adjusts tests to cover the new
dismissal/timing behavior (including `act()` wrapping for timer-driven
animations).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c63f170. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Add sanitized origin to sentinel metadata

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: Add sanitized origin to sentinel metadata

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds a new `origin` field to smart-transaction/relay metadata and
bumps `@metamask/smart-transactions-controller`, which could affect
downstream ingestion or controller behavior if payload expectations
differ.
> 
> **Overview**
> Adds `sanitizeOrigin` to normalize transaction origins for analytics
(URL origins reduced to hostname; internal origins preserved).
> 
> Smart transaction submission (`smart-publish-hook`) and the EIP-7702
relay publish hook now attach `origin:
sanitizeOrigin(transactionMeta.origin)` alongside existing
`txType`/`client` metadata, with new unit tests covering
URL/internal/empty cases. Also bumps
`@metamask/smart-transactions-controller` to `^22.4.0`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7c6d2ef. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

This PR migrates the `EndOfSeasonClaimBottomSheet` component from the
legacy `useMetrics` hook to the new `useAnalytics` hook as part of the
analytics migration effort (MCWP-297 batch 1-5 for rewards).

- update both the component implementation and its test.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: null

## **Related issues**

Fixes:
[MCWP-297](https://consensyssoftware.atlassian.net/browse/MCWP-297)

## **Manual testing steps**

```gherkin
Feature: Rewards claim analytics tracking

  Scenario: user claims a reward
    Given user has a claimable reward available
    And the user opted-in for analytics

    When user opens the rewards claim bottom sheet
    And user successfully claims a reward
    Then "Rewards Reward Viewed" and "Rewards Reward Claimed" events are tracked
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

NA

### **After**

NA

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


[MCWP-297]:
https://consensyssoftware.atlassian.net/browse/MCWP-297?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk refactor limited to swapping the analytics hook used by
`EndOfSeasonClaimBottomSheet`; behavior should remain the same aside
from how events are dispatched.
> 
> **Overview**
> Migrates `EndOfSeasonClaimBottomSheet` analytics tracking from legacy
`useMetrics` to the new `useAnalytics` hook while keeping event
constants (`MetaMetricsEvents`) sourced from `useMetrics`.
> 
> Updates the associated Jest test to mock `useAnalytics` instead of
`useMetrics`, preserving coverage for the "reward viewed" and "reward
claimed" tracking.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ff90e39. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@pull pull Bot locked and limited conversation to collaborators Feb 4, 2026
@pull pull Bot added the ⤵️ pull label Feb 4, 2026
@pull pull Bot merged commit ba8fa85 into Reality2byte:main Feb 4, 2026
1 of 11 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.